<script setup lang="ts">
import type { ComponentOptions, FormBasicConfig } from '../componentPanel/index'
import { ElForm, ElFormItem } from 'element-plus'
import { ref } from 'vue'
import { getComponent } from '../componentPanel/index'
import { generateFormRules, parseAttrs, parseEvent } from '../utils'

const props = withDefaults(
  defineProps<{
    formConfig?: {
      components: ComponentOptions[]
      formBasicConfig: FormBasicConfig
    }
  }>(),
  {
    formConfig: () => ({
      components: [
        {
          id: 1,
          span: 12,
          component: 'input',
          field: 'name',
          required: false,
          label: '输入框',
          defaultValue: '',
          labelWidth: 100,
          attrs: {
            placeholder: '请输入',
            showWordLimit: true,
            maxLength: 10,
            clearable: true,
          },
        },
        {
          id: 3,
          span: 12,
          component: 'checkbox',
          field: 'gender',
          required: true,
          label: '复选框',
          defaultValue: '',
          labelWidth: 100,
          attrs: { placeholder: '请选择' },
        },
        {
          id: 3,
          span: 12,
          component: 'checkbox',
          field: 'gender',
          required: true,
          label: '复选框',
          defaultValue: '',
          labelWidth: 100,
          attrs: { placeholder: '请选择' },
        },
      ],
      formBasicConfig: {
        totalColumns: 24,
        gridGap: 4,
        description: '这是一个表单',
      },
    }),
  },
)
const emit = defineEmits(['submit', 'reset'])
const _formConfig = computed(() => {
  return {
    formBasicConfig: props.formConfig.formBasicConfig,
    components: props.formConfig.components.map((v: any) => {
      return {
        ...v,
        attrs: parseAttrs(v.attrs),
        event: parseEvent(v.event),
        rules: generateFormRules(v.rules),
        component: getComponent(v.component),
        componentStr: v.component,
      }
    }),

  }
})

const formModel = ref<Record<string, any>>({
})
const formRules = ref<Record<string, any>>({})
function initFormData() {
  props.formConfig.components.forEach((item) => {
    const cusField = item.field as keyof typeof formModel.value
    if (cusField) {
      formModel.value[cusField] = item.defaultValue
    }
  })
}
initFormData()

const formRef = ref<InstanceType<typeof ElForm>>()
async function handleSubmit() {
  await formRef.value?.validate()
  emit('submit', formModel.value)
}
async function handleReset() {
  await formRef.value?.resetFields()
  emit('reset')
}

defineExpose({
  handleSubmit,
  handleReset,
})
</script>

<template>
  <ElForm ref="formRef" :model="formModel" :rules="formRules">
    <div
      :style="{
        display: 'grid',
        gridTemplateColumns: `repeat(${props.formConfig.formBasicConfig.totalColumns}, 1fr)`,
        gap: `${props.formConfig.formBasicConfig.gridGap}px`,
      }"
    >
      <div
        v-for="(element) in _formConfig.components" :key="element.id" :style="{
          gridColumn: `span ${element.span}`,
        }"
      >
        <ElFormItem
          :label="element.label" :prop="element.field" :label-width="element.labelWidth" :rules="element.rules"
        >
          <component :is="element.component" v-model="formModel[element.field]" v-bind="element.attrs" v-on="element.event">
            <template v-if="element.componentStr === 'select'">
              <ElOption
                v-for="item in element.selectOptions" :key="item.value" :label="item.label"
                :value="item.value" :disabled="element.attrs.disabled"
              />
            </template>
            <template v-if="element.componentStr === 'radioGroup'">
              <ElRadio
                v-for="item in element.selectOptions" :key="item.value" :label="item.value"
                :disabled="element.attrs.disabled"
              >
                {{ item.label }}
              </ElRadio>
            </template>
            <template v-if="element.componentStr === 'checkboxGroup'">
              <ElCheckbox
                v-for="item in element.selectOptions" :key="item.value" :label="item.value"
                :disabled="element.attrs.disabled"
              >
                {{ item.label }}
              </ElCheckbox>
            </template>
          </component>
        </ElFormItem>
      </div>
    </div>
    <ElFormItem>
      <div class="w-full flex justify-end">
        <ElSpace>
          <ElButton type="primary" @click="handleSubmit">
            提交
          </ElButton>
          <ElButton type="primary" plain @click="handleSubmit">
            重置
          </ElButton>
        </ElSpace>
      </div>
    </ElFormItem>
  </ElForm>
</template>
